package com.egao.common.core.exception;

import cn.hutool.core.util.StrUtil;
import com.egao.common.core.web.JsonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;

/**
 * 全局异常处理器
 * @author system
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class.getName());

    @ResponseBody
    @ExceptionHandler(Exception.class)
    public JsonResult errorHandler(Exception ex, HttpServletResponse response) {
        // 支持跨域
        cross(response);

        // 对不同错误进行不同处理
        if (ex instanceof IException) {
            return JsonResult.error(((IException) ex).getCode(), ex.getMessage());
        } else if (ex instanceof AccessDeniedException) {
            return JsonResult.error(403, "没有访问权限");
        } else if (ex instanceof MethodArgumentNotValidException) {
            StringBuilder errorMsg = new StringBuilder();
            for (ObjectError error : ((MethodArgumentNotValidException) ex).getBindingResult().getAllErrors()) {
                errorMsg.append(error.getDefaultMessage()).append(",");
            }
            errorMsg.delete(errorMsg.length() - 1, errorMsg.length());
            return JsonResult.error(errorMsg.toString());
        }

        // 不记录此异常到日志
        if (!StrUtil.contains(ex.getMessage(), "远程主机强迫关闭了一个现有的连接")) {
            logger.error(ex.getMessage(), ex);
        }

        String error = ex.toString();
        if (StrUtil.contains(error, "SELECT")) {
            error = "系统错误!";
        }
        if (StrUtil.contains(error, "UPDATE")) {
            error = "系统错误!";
        }
        if (StrUtil.contains(error, "DELETE")) {
            error = "系统错误!";
        }
        if (StrUtil.contains(error, "INSERT")) {
            error = "系统错误!";
        }
        if (StrUtil.contains(error, "FROM")) {
            error = "系统错误!";
        }
        if (StrUtil.contains(error, "Error querying database")) {
            error = "系统错误!";
        }
        return JsonResult.error("系统错误").put("error", error);
    }

    private void cross(HttpServletResponse response) {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, X-Custom-Header, Authorization");
    }

}
